package algorithm.recursion.tree.sf_tree;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.codehaus.jackson.map.ObjectMapper;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 模拟顺丰云平台组织树
 *
 * @author hupan
 * @date 2021-07-14 23:56
 */
public class Tree {

	private final static boolean SHOW_ROOT = true;
	private final static int USER_AREA_ID = 10011;

	private static List<Area> areaList = new ArrayList<>(2);
	private static List<Depot> depotList = new ArrayList<>(4);
	private static List<SubDepot> subDepotList = new ArrayList<>(5);


	public static void init() {
		areaList.add(new Area(1001, 0, "QG", "全国", 3));
		areaList.add(new Area(10011, 1001, "LWZZ", "理文造纸厂", 2));
		areaList.add(new Area(10012, 1001, "LWZZ", "海康威视", 2));

		depotList.add(new Depot(2001, null, "GDLW", "广东理文", 10011, 1));
		depotList.add(new Depot(2002, null, "HNLW", "河南理文", 10011, 1));
		depotList.add(new Depot(20011, 2001, "GZLW", "广州理文", 10011, 1));
		depotList.add(new Depot(20012, 2001, "SZLW", "深圳理文", 10011, 1));

		subDepotList.add(new SubDepot(3001, null, "BALW", "宝安理文", 20012, 0));
		subDepotList.add(new SubDepot(3002, null, "LHLW", "龙华理文", 20012, 0));
		subDepotList.add(new SubDepot(30011, 3001, "XXLW", "西乡理文", 20012, 0));
		subDepotList.add(new SubDepot(30012, 3001, "XALW", "新安理文", 20012, 0));
		subDepotList.add(new SubDepot(30013, 3001, "SYLW", "石岩理文", 20012, 0));
	}

	public static void main(String[] args) throws IOException {
		init();

		Node node = buildChilTree(getRootNode());

//		ObjectMapper objectMapper = new ObjectMapper();
//		System.out.println(objectMapper.writeValueAsString(node));

		System.out.println(JSON.toJSONString(node, SerializerFeature.WriteMapNullValue));
	}

	// 递归，建立子树形结构
	private static <T extends Node> Node buildChilTree(T node) {
		// 节点是分拨区，则查询下面的场区作为孩子
		if (node instanceof Area) {
			List<Area> areaList = Tree.areaList.stream().filter(e -> e.getPid().equals(((Area) node).getAreaId()))
					.collect(Collectors.toList());
			List<Depot> depotList = Tree.depotList.stream()
					.filter(e -> e.getPid() == null)
					.filter(e -> e.getAreaId().equals(((Area) node).getAreaId()))
					.collect(Collectors.toList());

			List<Node> children = Stream.of(areaList, depotList).flatMap(Collection::stream).map(Tree::buildChilTree)
					.collect(Collectors.toList());

			return node.setChildren(children);
		}

		if (node instanceof Depot) {
			List<Depot> depotList = Tree.depotList.stream().filter(e -> ((Depot) node).getDepotId().equals(e.getPid()))
					.collect(Collectors.toList());
			List<SubDepot> subDepotList = Tree.subDepotList.stream()
					.filter(e -> e.getPid() == null)
					.filter(e -> e.getDepotId().equals(((Depot) node).getDepotId()))
					.collect(Collectors.toList());

			List<Node> children = Stream.of(depotList, subDepotList).flatMap(Collection::stream).map(Tree::buildChilTree)
					.collect(Collectors.toList());
			return node.setChildren(children);
		}

		if (node instanceof SubDepot) {
			List<SubDepot> subDepotList = Tree.subDepotList.stream()
					.filter(e -> ((SubDepot) node).getSubDepotId().equals(e.getPid()))
					.collect(Collectors.toList());
			return node.setChildren(subDepotList);
		}

		return node;
	}

	// 获取根节点
	private static Area getRootNode() {
		if (SHOW_ROOT) {
			Optional<Area> optional = areaList.stream().filter(e -> e.getPid() == 0).findFirst();
			return optional.orElse(null);
		}

		Optional<Area> optional = areaList.stream().filter(e -> e.getAreaId() == USER_AREA_ID).findFirst();
		return optional.orElse(null);
	}


}
